/**
 *    ------------------------------------------------------------------------------------------
 *    PExpenses version 1.0
 *    ------------------------------------------------------------------------------------------
 *    PExpenses is a financial tool to track personal expenses with a quick and user friendly gui.
 *    ------------------------------------------------------------------------------------------
 *    Author			: M. Kaisar-Ul-Haque
 *    E-mail			: m.kaisar@gmail.com
 *    Author Blog	: http://kaisar-haque.blogspot.com
 *    Project Web : http://code.google.com/p/pexpenses
 *    Created		: June 23, 2007
 *    ------------------------------------------------------------------------------------------
 *    Copyright (C) 2007 M. Kaisar-Ul-Haque <m.kaisar@gmail.com>
 *    ------------------------------------------------------------------------------------------
 *    This program is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU General Public License
 *    as published by the Free Software Foundation; either version 2
 *    of the License, or (at your option) any later version.
 *
 *    This program is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License
 *    along with this program; if not, write to the Free Software
 *    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 *    ------------------------------------------------------------------------------------------
*/

/**
 * PExpenseMidlet.java
 *
 * Created on June 23, 2007, 10:38 PM
 */

package kaisar;

import javax.microedition.rms.*;
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;

import java.util.Date;

/**
 *
 * @author Kaisar
 */
public class PExpensesMidlet extends MIDlet implements javax.microedition.lcdui.CommandListener {

    RecordStoreManager data;
    RecordStoreManager settings;
    boolean firstTime = false;

    /** Creates a new instance of PExpenseMidlet */
    public PExpensesMidlet() {
        data = new RecordStoreManager("PExpenseData");
        settings = new RecordStoreManager("PExpenseSettings");
    }
    
    private Command exitCommand;//GEN-BEGIN:MVDFields
    private Form frmLogin;
    private TextField txtPass;
    private Command okPass;
    private Command exitPass;
    private Form frmEntry;
    private Command okEntry;
    private Command cancelEntry;
    private TextField txtAmount;
    private TextField txtDesc;
    private DateField txtDate;
    private Font font1;
    private Command reportMain;
    private Command exportMain;
    private Command exitMain;
    private ChoiceGroup choiceType;
    private Form frmSettings;
    private ChoiceGroup choicePass;
    private TextField txtPass1;
    private TextField txtPass2;
    private Command okSettings;
    private Command cancelSettings;
    private ChoiceGroup choiceNewEntry;
    private Command settingsMain;
    private Command aboutMain;
    private TextField textField1;
    private Command newEntryMain;
    private StringItem strList;
    private Form frmList;
    private ChoiceGroup grpType;//GEN-END:MVDFields

//GEN-LINE:MVDMethods

    /** This method initializes UI of the application.//GEN-BEGIN:MVDInitBegin
     */
    private void initialize() {//GEN-END:MVDInitBegin
        // Insert pre-init code here
        getDisplay().setCurrent(get_frmLogin());//GEN-LINE:MVDInitInit
        // Insert post-init code here
    }//GEN-LINE:MVDInitEnd

    /**
     * This method should return an instance of the display.
     */
    public Display getDisplay () {//GEN-FIRST:MVDGetDisplay
        return Display.getDisplay (this);
    }//GEN-LAST:MVDGetDisplay

    /**
     * This method should exit the midlet.
     */
    public void exitMIDlet () {//GEN-FIRST:MVDExitMidlet
        getDisplay ().setCurrent (null);
        destroyApp (true);
        notifyDestroyed ();
    }//GEN-LAST:MVDExitMidlet

    /** Called by the system to indicate that a command has been invoked on a particular displayable.//GEN-BEGIN:MVDCABegin
     * @param command the Command that ws invoked
     * @param displayable the Displayable on which the command was invoked
     */
    public void commandAction(Command command, Displayable displayable) {//GEN-END:MVDCABegin
    // Insert global pre-action code here
        if (displayable == frmLogin) {//GEN-BEGIN:MVDCABody
            if (command == okPass) {//GEN-END:MVDCABody
                // Insert pre-action code here
                // Do nothing//GEN-LINE:MVDCAAction6
                checkPass();
            } else if (command == exitPass) {//GEN-LINE:MVDCACase6
                // Insert pre-action code here
                exitMIDlet();//GEN-LINE:MVDCAAction8
                // Insert post-action code here
            }//GEN-BEGIN:MVDCACase8
        } else if (displayable == frmEntry) {
            if (command == okEntry) {//GEN-END:MVDCACase8
                // Insert pre-action code here
                // Do nothing//GEN-LINE:MVDCAAction11
                newEntry();
            } else if (command == cancelEntry) {//GEN-LINE:MVDCACase11
                // Insert pre-action code here
                getDisplay().setCurrent(get_frmList());//GEN-LINE:MVDCAAction13
                // Insert post-action code here
            }//GEN-BEGIN:MVDCACase13
        } else if (displayable == frmList) {
            if (command == reportMain) {//GEN-END:MVDCACase13
                // Insert pre-action code here
                // Do nothing//GEN-LINE:MVDCAAction43
                report();
            } else if (command == exitMain) {//GEN-LINE:MVDCACase43
                // Insert pre-action code here
                exitMIDlet();//GEN-LINE:MVDCAAction44
                // Insert post-action code here
            } else if (command == exportMain) {//GEN-LINE:MVDCACase44
                // Insert pre-action code here
                // Do nothing//GEN-LINE:MVDCAAction41
                // Insert post-action code here
            } else if (command == newEntryMain) {//GEN-LINE:MVDCACase41
                // Insert pre-action code here
                getDisplay().setCurrent(get_frmEntry());//GEN-LINE:MVDCAAction39
                // Insert post-action code here
            } else if (command == aboutMain) {//GEN-LINE:MVDCACase39
                // Insert pre-action code here
                // Do nothing//GEN-LINE:MVDCAAction38
                showAlert("About", "Personal Expenses v1.0 by M. Kaisar-Ul-Haque. Web: kaisar-haque.blogspot.com, E-mail: m.kaisar@gmail.com", get_frmList());
            } else if (command == settingsMain) {//GEN-LINE:MVDCACase38
                // Insert pre-action code here
                getDisplay().setCurrent(get_frmSettings());//GEN-LINE:MVDCAAction40
                // Insert post-action code here
            }//GEN-BEGIN:MVDCACase40
        } else if (displayable == frmSettings) {
            if (command == cancelSettings) {//GEN-END:MVDCACase40
                // Insert pre-action code here
                // Do nothing//GEN-LINE:MVDCAAction30
                if (firstTime) {
                    destroyApp(true);
                    notifyDestroyed();
                } else
                    showForm(get_frmList());
            } else if (command == okSettings) {//GEN-LINE:MVDCACase30
                // Insert pre-action code here
                // Do nothing//GEN-LINE:MVDCAAction28
                saveSettings();
            }//GEN-BEGIN:MVDCACase28
        }//GEN-END:MVDCACase28
    // Insert global post-action code here
    }//GEN-LINE:MVDCAEnd

    /** This method returns instance for exitCommand component and should be called instead of accessing exitCommand field directly.//GEN-BEGIN:MVDGetBegin2
     * @return Instance for exitCommand component
     */
    public Command get_exitCommand() {
        if (exitCommand == null) {//GEN-END:MVDGetBegin2
            // Insert pre-init code here
            exitCommand = new Command("Exit", Command.EXIT, 1);//GEN-LINE:MVDGetInit2
            // Insert post-init code here
        }//GEN-BEGIN:MVDGetEnd2
        return exitCommand;
    }//GEN-END:MVDGetEnd2

    /** This method returns instance for frmLogin component and should be called instead of accessing frmLogin field directly.//GEN-BEGIN:MVDGetBegin3
     * @return Instance for frmLogin component
     */
    public Form get_frmLogin() {
        if (frmLogin == null) {//GEN-END:MVDGetBegin3
            // Insert pre-init code here
            frmLogin = new Form("PExpenses Login", new Item[] {get_txtPass()});//GEN-BEGIN:MVDGetInit3
            frmLogin.addCommand(get_okPass());
            frmLogin.addCommand(get_exitPass());
            frmLogin.setCommandListener(this);//GEN-END:MVDGetInit3
            // Insert post-init code here
        }//GEN-BEGIN:MVDGetEnd3
        return frmLogin;
    }//GEN-END:MVDGetEnd3

    /** This method returns instance for txtPass component and should be called instead of accessing txtPass field directly.//GEN-BEGIN:MVDGetBegin4
     * @return Instance for txtPass component
     */
    public TextField get_txtPass() {
        if (txtPass == null) {//GEN-END:MVDGetBegin4
            // Insert pre-init code here
            txtPass = new TextField("Enter Password", "", 120, TextField.ANY | TextField.PASSWORD);//GEN-LINE:MVDGetInit4
            // Insert post-init code here
        }//GEN-BEGIN:MVDGetEnd4
        return txtPass;
    }//GEN-END:MVDGetEnd4

    /** This method returns instance for okPass component and should be called instead of accessing okPass field directly.//GEN-BEGIN:MVDGetBegin5
     * @return Instance for okPass component
     */
    public Command get_okPass() {
        if (okPass == null) {//GEN-END:MVDGetBegin5
            // Insert pre-init code here
            okPass = new Command("Ok", Command.OK, 1);//GEN-LINE:MVDGetInit5
            // Insert post-init code here
        }//GEN-BEGIN:MVDGetEnd5
        return okPass;
    }//GEN-END:MVDGetEnd5

    /** This method returns instance for exitPass component and should be called instead of accessing exitPass field directly.//GEN-BEGIN:MVDGetBegin7
     * @return Instance for exitPass component
     */
    public Command get_exitPass() {
        if (exitPass == null) {//GEN-END:MVDGetBegin7
            // Insert pre-init code here
            exitPass = new Command("Exit", Command.EXIT, 1);//GEN-LINE:MVDGetInit7
            // Insert post-init code here
        }//GEN-BEGIN:MVDGetEnd7
        return exitPass;
    }//GEN-END:MVDGetEnd7

    /** This method returns instance for frmEntry component and should be called instead of accessing frmEntry field directly.//GEN-BEGIN:MVDGetBegin9
     * @return Instance for frmEntry component
     */
    public Form get_frmEntry() {
        if (frmEntry == null) {//GEN-END:MVDGetBegin9
            // Insert pre-init code here
            frmEntry = new Form("New Entry", new Item[] {//GEN-BEGIN:MVDGetInit9
                get_txtAmount(),
                get_txtDesc(),
                get_txtDate(),
                get_grpType(),
                get_choiceType()
            });
            frmEntry.addCommand(get_okEntry());
            frmEntry.addCommand(get_cancelEntry());
            frmEntry.setCommandListener(this);//GEN-END:MVDGetInit9
            txtDate.setDate(new Date());
        }//GEN-BEGIN:MVDGetEnd9
        return frmEntry;
    }//GEN-END:MVDGetEnd9

    /** This method returns instance for okEntry component and should be called instead of accessing okEntry field directly.//GEN-BEGIN:MVDGetBegin10
     * @return Instance for okEntry component
     */
    public Command get_okEntry() {
        if (okEntry == null) {//GEN-END:MVDGetBegin10
            // Insert pre-init code here
            okEntry = new Command("Ok", Command.OK, 1);//GEN-LINE:MVDGetInit10
            // Insert post-init code here
        }//GEN-BEGIN:MVDGetEnd10
        return okEntry;
    }//GEN-END:MVDGetEnd10

    /** This method returns instance for cancelEntry component and should be called instead of accessing cancelEntry field directly.//GEN-BEGIN:MVDGetBegin12
     * @return Instance for cancelEntry component
     */
    public Command get_cancelEntry() {
        if (cancelEntry == null) {//GEN-END:MVDGetBegin12
            // Insert pre-init code here
            cancelEntry = new Command("Cancel", Command.CANCEL, 1);//GEN-LINE:MVDGetInit12
            // Insert post-init code here
        }//GEN-BEGIN:MVDGetEnd12
        return cancelEntry;
    }//GEN-END:MVDGetEnd12

    /** This method returns instance for txtAmount component and should be called instead of accessing txtAmount field directly.//GEN-BEGIN:MVDGetBegin14
     * @return Instance for txtAmount component
     */
    public TextField get_txtAmount() {
        if (txtAmount == null) {//GEN-END:MVDGetBegin14
            // Insert pre-init code here
            txtAmount = new TextField("Amount", "", 120, TextField.DECIMAL);//GEN-LINE:MVDGetInit14
            // Insert post-init code here
        }//GEN-BEGIN:MVDGetEnd14
        return txtAmount;
    }//GEN-END:MVDGetEnd14

    /** This method returns instance for txtDesc component and should be called instead of accessing txtDesc field directly.//GEN-BEGIN:MVDGetBegin15
     * @return Instance for txtDesc component
     */
    public TextField get_txtDesc() {
        if (txtDesc == null) {//GEN-END:MVDGetBegin15
            // Insert pre-init code here
            txtDesc = new TextField("Description", null, 120, TextField.ANY);//GEN-LINE:MVDGetInit15
            // Insert post-init code here
        }//GEN-BEGIN:MVDGetEnd15
        return txtDesc;
    }//GEN-END:MVDGetEnd15

    /** This method returns instance for txtDate component and should be called instead of accessing txtDate field directly.//GEN-BEGIN:MVDGetBegin16
     * @return Instance for txtDate component
     */
    public DateField get_txtDate() {
        if (txtDate == null) {//GEN-END:MVDGetBegin16
            // Insert pre-init code here
            txtDate = new DateField("Date", DateField.DATE_TIME);//GEN-LINE:MVDGetInit16
            // Insert post-init code here
        }//GEN-BEGIN:MVDGetEnd16
        return txtDate;
    }//GEN-END:MVDGetEnd16

    /** This method returns instance for font1 component and should be called instead of accessing font1 field directly.//GEN-BEGIN:MVDGetBegin17
     * @return Instance for font1 component
     */
    public Font get_font1() {
        if (font1 == null) {//GEN-END:MVDGetBegin17
            // Insert pre-init code here
            font1 = Font.getDefaultFont();//GEN-LINE:MVDGetInit17
            // Insert post-init code here
        }//GEN-BEGIN:MVDGetEnd17
        return font1;
    }//GEN-END:MVDGetEnd17

    /** This method returns instance for reportMain component and should be called instead of accessing reportMain field directly.//GEN-BEGIN:MVDGetBegin18
     * @return Instance for reportMain component
     */
    public Command get_reportMain() {
        if (reportMain == null) {//GEN-END:MVDGetBegin18
            // Insert pre-init code here
            reportMain = new Command("Report Expenses", Command.OK, 1);//GEN-LINE:MVDGetInit18
            // Insert post-init code here
        }//GEN-BEGIN:MVDGetEnd18
        return reportMain;
    }//GEN-END:MVDGetEnd18

    /** This method returns instance for exportMain component and should be called instead of accessing exportMain field directly.//GEN-BEGIN:MVDGetBegin19
     * @return Instance for exportMain component
     */
    public Command get_exportMain() {
        if (exportMain == null) {//GEN-END:MVDGetBegin19
            // Insert pre-init code here
            exportMain = new Command("Export to CVS", Command.OK, 1);//GEN-LINE:MVDGetInit19
            // Insert post-init code here
        }//GEN-BEGIN:MVDGetEnd19
        return exportMain;
    }//GEN-END:MVDGetEnd19

    /** This method returns instance for exitMain component and should be called instead of accessing exitMain field directly.//GEN-BEGIN:MVDGetBegin20
     * @return Instance for exitMain component
     */
    public Command get_exitMain() {
        if (exitMain == null) {//GEN-END:MVDGetBegin20
            // Insert pre-init code here
            exitMain = new Command("Exit", Command.EXIT, 1);//GEN-LINE:MVDGetInit20
            // Insert post-init code here
        }//GEN-BEGIN:MVDGetEnd20
        return exitMain;
    }//GEN-END:MVDGetEnd20

    /** This method returns instance for choiceType component and should be called instead of accessing choiceType field directly.//GEN-BEGIN:MVDGetBegin21
     * @return Instance for choiceType component
     */
    public ChoiceGroup get_choiceType() {
        if (choiceType == null) {//GEN-END:MVDGetBegin21
            // Insert pre-init code here
            choiceType = new ChoiceGroup("", Choice.MULTIPLE, new String[0], new Image[0]);//GEN-BEGIN:MVDGetInit21
            choiceType.setSelectedFlags(new boolean[0]);//GEN-END:MVDGetInit21
            // Insert post-init code here
        }//GEN-BEGIN:MVDGetEnd21
        return choiceType;
    }//GEN-END:MVDGetEnd21

    /** This method returns instance for frmSettings component and should be called instead of accessing frmSettings field directly.//GEN-BEGIN:MVDGetBegin22
     * @return Instance for frmSettings component
     */
    public Form get_frmSettings() {
        if (frmSettings == null) {//GEN-END:MVDGetBegin22
            // Insert pre-init code here
            frmSettings = new Form("Settings", new Item[] {//GEN-BEGIN:MVDGetInit22
                get_choicePass(),
                get_txtPass1(),
                get_txtPass2(),
                get_choiceNewEntry()
            });
            frmSettings.addCommand(get_okSettings());
            frmSettings.addCommand(get_cancelSettings());
            frmSettings.setCommandListener(this);//GEN-END:MVDGetInit22
            loadSettings();
        }//GEN-BEGIN:MVDGetEnd22
        return frmSettings;
    }//GEN-END:MVDGetEnd22

    /** This method returns instance for choicePass component and should be called instead of accessing choicePass field directly.//GEN-BEGIN:MVDGetBegin23
     * @return Instance for choicePass component
     */
    public ChoiceGroup get_choicePass() {
        if (choicePass == null) {//GEN-END:MVDGetBegin23
            // Insert pre-init code here
            choicePass = new ChoiceGroup("Prompt for Password on Startup", Choice.MULTIPLE, new String[] {"Yes"}, new Image[] {null});//GEN-BEGIN:MVDGetInit23
            choicePass.setSelectedFlags(new boolean[] {false});//GEN-END:MVDGetInit23
            // Insert post-init code here
        }//GEN-BEGIN:MVDGetEnd23
        return choicePass;
    }//GEN-END:MVDGetEnd23

    /** This method returns instance for txtPass1 component and should be called instead of accessing txtPass1 field directly.//GEN-BEGIN:MVDGetBegin25
     * @return Instance for txtPass1 component
     */
    public TextField get_txtPass1() {
        if (txtPass1 == null) {//GEN-END:MVDGetBegin25
            // Insert pre-init code here
            txtPass1 = new TextField("Set Password", "", 120, TextField.ANY | TextField.PASSWORD);//GEN-LINE:MVDGetInit25
            // Insert post-init code here
        }//GEN-BEGIN:MVDGetEnd25
        return txtPass1;
    }//GEN-END:MVDGetEnd25

    /** This method returns instance for txtPass2 component and should be called instead of accessing txtPass2 field directly.//GEN-BEGIN:MVDGetBegin26
     * @return Instance for txtPass2 component
     */
    public TextField get_txtPass2() {
        if (txtPass2 == null) {//GEN-END:MVDGetBegin26
            // Insert pre-init code here
            txtPass2 = new TextField("Confirm Password", "", 120, TextField.ANY | TextField.PASSWORD);//GEN-LINE:MVDGetInit26
            // Insert post-init code here
        }//GEN-BEGIN:MVDGetEnd26
        return txtPass2;
    }//GEN-END:MVDGetEnd26

    /** This method returns instance for okSettings component and should be called instead of accessing okSettings field directly.//GEN-BEGIN:MVDGetBegin27
     * @return Instance for okSettings component
     */
    public Command get_okSettings() {
        if (okSettings == null) {//GEN-END:MVDGetBegin27
            // Insert pre-init code here
            okSettings = new Command("Ok", Command.OK, 1);//GEN-LINE:MVDGetInit27
            // Insert post-init code here
        }//GEN-BEGIN:MVDGetEnd27
        return okSettings;
    }//GEN-END:MVDGetEnd27

    /** This method returns instance for cancelSettings component and should be called instead of accessing cancelSettings field directly.//GEN-BEGIN:MVDGetBegin29
     * @return Instance for cancelSettings component
     */
    public Command get_cancelSettings() {
        if (cancelSettings == null) {//GEN-END:MVDGetBegin29
            // Insert pre-init code here
            cancelSettings = new Command("Cancel", Command.CANCEL, 1);//GEN-LINE:MVDGetInit29
            // Insert post-init code here
        }//GEN-BEGIN:MVDGetEnd29
        return cancelSettings;
    }//GEN-END:MVDGetEnd29

    /** This method returns instance for choiceNewEntry component and should be called instead of accessing choiceNewEntry field directly.//GEN-BEGIN:MVDGetBegin31
     * @return Instance for choiceNewEntry component
     */
    public ChoiceGroup get_choiceNewEntry() {
        if (choiceNewEntry == null) {//GEN-END:MVDGetBegin31
            // Insert pre-init code here
            choiceNewEntry = new ChoiceGroup("Prompt for New Entry on Startup", Choice.MULTIPLE, new String[] {"Yes"}, new Image[] {null});//GEN-BEGIN:MVDGetInit31
            choiceNewEntry.setSelectedFlags(new boolean[] {false});//GEN-END:MVDGetInit31
            // Insert post-init code here
        }//GEN-BEGIN:MVDGetEnd31
        return choiceNewEntry;
    }//GEN-END:MVDGetEnd31

    /** This method returns instance for settingsMain component and should be called instead of accessing settingsMain field directly.//GEN-BEGIN:MVDGetBegin33
     * @return Instance for settingsMain component
     */
    public Command get_settingsMain() {
        if (settingsMain == null) {//GEN-END:MVDGetBegin33
            // Insert pre-init code here
            settingsMain = new Command("Settings..", Command.OK, 1);//GEN-LINE:MVDGetInit33
            // Insert post-init code here
        }//GEN-BEGIN:MVDGetEnd33
        return settingsMain;
    }//GEN-END:MVDGetEnd33

    /** This method returns instance for aboutMain component and should be called instead of accessing aboutMain field directly.//GEN-BEGIN:MVDGetBegin34
     * @return Instance for aboutMain component
     */
    public Command get_aboutMain() {
        if (aboutMain == null) {//GEN-END:MVDGetBegin34
            // Insert pre-init code here
            aboutMain = new Command("About..", Command.OK, 1);//GEN-LINE:MVDGetInit34
            // Insert post-init code here
        }//GEN-BEGIN:MVDGetEnd34
        return aboutMain;
    }//GEN-END:MVDGetEnd34

    /** This method returns instance for textField1 component and should be called instead of accessing textField1 field directly.//GEN-BEGIN:MVDGetBegin35
     * @return Instance for textField1 component
     */
    public TextField get_textField1() {
        if (textField1 == null) {//GEN-END:MVDGetBegin35
            // Insert pre-init code here
            textField1 = new TextField("textField1", null, 120, TextField.ANY);//GEN-LINE:MVDGetInit35
            // Insert post-init code here
        }//GEN-BEGIN:MVDGetEnd35
        return textField1;
    }//GEN-END:MVDGetEnd35

    /** This method returns instance for newEntryMain component and should be called instead of accessing newEntryMain field directly.//GEN-BEGIN:MVDGetBegin36
     * @return Instance for newEntryMain component
     */
    public Command get_newEntryMain() {
        if (newEntryMain == null) {//GEN-END:MVDGetBegin36
            // Insert pre-init code here
            newEntryMain = new Command("New Entry", Command.OK, 1);//GEN-LINE:MVDGetInit36
            // Insert post-init code here
        }//GEN-BEGIN:MVDGetEnd36
        return newEntryMain;
    }//GEN-END:MVDGetEnd36

    /** This method returns instance for strList component and should be called instead of accessing strList field directly.//GEN-BEGIN:MVDGetBegin42
     * @return Instance for strList component
     */
    public StringItem get_strList() {
        if (strList == null) {//GEN-END:MVDGetBegin42
            // Insert pre-init code here
            strList = new StringItem("", "");//GEN-LINE:MVDGetInit42
            // Insert post-init code here
        }//GEN-BEGIN:MVDGetEnd42
        return strList;
    }//GEN-END:MVDGetEnd42

    /** This method returns instance for frmList component and should be called instead of accessing frmList field directly.//GEN-BEGIN:MVDGetBegin45
     * @return Instance for frmList component
     */
    public Form get_frmList() {
        if (frmList == null) {//GEN-END:MVDGetBegin45
            // Insert pre-init code here
            frmList = new Form("PExpenses by Kaisar", new Item[] {get_strList()});//GEN-BEGIN:MVDGetInit45
            frmList.addCommand(get_newEntryMain());
            frmList.addCommand(get_reportMain());
            frmList.addCommand(get_exportMain());
            frmList.addCommand(get_settingsMain());
            frmList.addCommand(get_aboutMain());
            frmList.addCommand(get_exitMain());
            frmList.setCommandListener(this);//GEN-END:MVDGetInit45
            // Insert post-init code here
        }//GEN-BEGIN:MVDGetEnd45
        return frmList;
    }//GEN-END:MVDGetEnd45

    /** This method returns instance for grpType component and should be called instead of accessing grpType field directly.//GEN-BEGIN:MVDGetBegin46
     * @return Instance for grpType component
     */
    public ChoiceGroup get_grpType() {
        if (grpType == null) {//GEN-END:MVDGetBegin46
            // Insert pre-init code here
            grpType = new ChoiceGroup("Type", Choice.EXCLUSIVE, new String[] {//GEN-BEGIN:MVDGetInit46
                "I\'ve spent (Debit)",
                "I\'ve received/earned (Credit)",
                "I\'ve withdrawn from Bank (Credit)",
                "Balance"
            }, new Image[] {
                null,
                null,
                null,
                null
            });
            grpType.setSelectedFlags(new boolean[] {
                false,
                false,
                false,
                false
            });//GEN-END:MVDGetInit46
            // Insert post-init code here
        }//GEN-BEGIN:MVDGetEnd46
        return grpType;
    }//GEN-END:MVDGetEnd46
    
    public boolean isFirstTime()
    {
        String d = settings.read(1);
        
        if (d == null)
        {
            firstTime = true;
            showAlert("Welcome", "Welcome to Kaisar's PersonalExpenses v1.0. Please setup your preferrences.", get_frmSettings());
            return true;
        }
        return false;
    }
    
    public boolean getSetting(int id)
    {
        String d = settings.read(id);
        return d.equals("1");
    }
    
    public void startApp()
    {
        if (isFirstTime())
            return;

        if (getSetting(1)) //show login?
        {
            showForm(get_frmLogin());
            return;
        }
        
        if (getSetting(3))  //show new entry?
            showForm(get_frmEntry());
        else
            showForm(get_frmList());
    }
    
    public void pauseApp() {
    }
    
    public void destroyApp(boolean unconditional) {
    }
    
    public void checkPass()
    {
        String pass = settings.read(2);
        
        if (txtPass.getString().equals(pass))
        {
            if (getSetting(3))  //show new entry?
                showForm(get_frmEntry());
            else
                showForm(get_frmList());
        }
        else
        {
            txtPass.setString("");
            showAlert("Error", "Invalid Password", get_frmLogin());
        }
    }
    
    public void newEntry()
    {
        /*
         * Write to database
         */
        data.append(txtDate.getDate().toString());
        
        showAlert("Selected", "Index " + grpType.getSelectedIndex(), get_frmEntry());

        data.append(txtDesc.getString());
        
        if (grpType.getSelectedIndex() == 0)
        {
            data.append("-" + txtAmount.getString());
        }
        else if (grpType.getSelectedIndex() <= 2) //for 1 and 2
        {
            data.append("+" + txtAmount.getString());
        }
        
        txtAmount.setString("");
        txtDesc.setString("");
        setFocus(txtAmount);
    }
    
    public void report()
    {
        RecordStore rs = data.getRecordStore();
        byte[] recData = new byte[64];
        int len, c;

        String date="", amount = "", desc = "", s, lastDate="";
        StringBuffer buf = new StringBuffer();
        
        buf.append("\n");
        try
        {
            c = 0;
            for (int i = 1; i <= rs.getNumRecords(); i++)
            {
                if (rs.getRecordSize(i) > recData.length)
                    recData = new byte[rs.getRecordSize(i)];

                len = rs.getRecord(i, recData, 0);
                s = new String(recData, 0, len);
                
                if (c == 0)
                    date = s;
                else if (c == 1)
                    desc = s;
                else if (c == 2)
                {
                    amount = s;
                
                    if (!date.equals(lastDate))
                        buf.append(date + "\n");

                    buf.append(desc + " : " + amount + "\n");
                    lastDate = date;
                }
                c++;
                c = c % 3;
            }
        }
        catch(Exception error)
        {
            System.err.println(error.toString());
        }
        
        strList.setText(buf.toString());
    }
    
    public void loadSettings()
    {
        if (firstTime)
            return;
        
        choicePass.setSelectedIndex(0, getSetting(1));
        txtPass1.setString(settings.read(2));
        txtPass2.setString(settings.read(2));
        choiceNewEntry.setSelectedIndex(0, getSetting(3));
    }
    
    public void saveSettings()
    {
        if (!txtPass1.getString().equals(txtPass2.getString()))
        {
            showAlert("Error", "Two passwords are not identical!", get_frmSettings());
            return;
        }

        if (firstTime)
        {
            settings.append("1");   //record 1, prompt password
            settings.append("");    //record 2, password
            settings.append("1");    //record 3, prompt new entry
        }
        
        settings.write(1, choicePass.isSelected(0) ? "1" : "0");
        settings.write(2, txtPass1.getString());
        settings.write(3, choiceNewEntry.isSelected(0) ? "1" : "0");
        
        if (firstTime)
        {
            firstTime = false;
            startApp();
        }
        else
            showForm(get_frmList());
    }
    /*
     * Utility functions
     */
    public void showForm(Form frm)
    {
        javax.microedition.lcdui.Display.getDisplay(this).setCurrent(frm);
    }

    public void showAlert(String title, String msg, Form frm)
    {
          Alert alert = new Alert(title, msg, null, AlertType.INFO);
          alert.setTimeout(Alert.FOREVER);
          
          javax.microedition.lcdui.Display.getDisplay(this).setCurrent(alert, frm);
    }
    
    public void setFocus(Item item)
    {
        javax.microedition.lcdui.Display.getDisplay(this).setCurrentItem(item);
    }
}
